package com.ra.landlord;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.JoinColumnOrFormula;
import org.hibernate.annotations.JoinColumnsOrFormulas;
import org.hibernate.annotations.JoinFormula;
import org.hibernate.annotations.Where;

import com.ra.system.Version;
import com.ra.util.Address;

/**
 * Building
 * 
 * @author Jerry.Feng Date: 2014-07-30
 */
@Entity
@Table(name = "ra_building")
@Where(clause = "data_status = 1")
public class Building implements Version, LandlordOwner {

	//整租
	public static final Integer RENT_TYPE_ENTIRE = 0;
	
	//合租
	public static final Integer RENT_TYPE_SHARE = 1;
	
	private Integer id;
	
	private String name;
	
	private Address address;
	
	private String detailAddress;
	
	private String description;
	
	private String phoneNum;
	
	// 楼层总数
	private Integer floorCount;
	
	// 房间总数
	private Integer roomCount;
	
	// 房屋创建时间 
	private String buildingTime;
	
	// 是否有电梯
	private Boolean elevator;
	
	// TODO: 租金支付模式： 比方： 押一付一， 押一付二等 
	private Integer rentPayMode;
	
	// 收费周期  (客户填写，目前废弃)
	private Integer depositFeeType;
	
	// 出租周期 （一种缺省值）
	private Integer rentCycle;
	
	private List<Room> rooms;
	
	private List<BuildingFloor> buildingFloors;
	
	private List<LandlordUser> landlordUsers;
	
	private LandlordOwnerUser landlordUser;
	
	// 创建时间
	private Date createTime;
	
	private Integer version;
	
	private Integer status;
	
	//-
	//每层房间数
	private Integer roomsPerFloor;
	
	//出租方式: 0整组; 1合租; (批量建楼时使用)
	private Integer rentType;

	@Id
	@GeneratedValue
	@Column(name = "buildings_id")
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name = "building_name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name = "Buildingaddress")
	public String getDetailAddress() {
		return detailAddress;
	}

	public void setDetailAddress(String detailAddress) {
		this.detailAddress = detailAddress;
	}

	@Column(name = "BuildingNotice")
	public String getDescription() {
		return description;
	}

	public void setDescription(String notice) {
		this.description = notice;
	}

	@Column(name = "phone_num")
	public String getPhoneNum() {
		return phoneNum;
	}

	public void setPhoneNum(String phoneNum) {
		this.phoneNum = phoneNum;
	}

	@OneToMany(targetEntity=Room.class, fetch=FetchType.LAZY, mappedBy="building", cascade=CascadeType.ALL, orphanRemoval=true)
	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@Where(clause = "data_status = 1")
	public List<Room> getRooms() {
		return rooms;
	}

	public void setRooms(List<Room> rooms) {
		this.rooms = rooms;
	}
	
	@OneToMany(targetEntity=BuildingFloor.class, fetch=FetchType.LAZY, mappedBy="building", cascade=CascadeType.ALL, orphanRemoval=true)
	@OrderBy("no asc")
	@Where(clause = "data_status = 1")
	public List<BuildingFloor> getBuildingFloors() {
		return buildingFloors;
	}

	public void setBuildingFloors(List<BuildingFloor> buildingFloors) {
		this.buildingFloors = buildingFloors;
	}

	@ManyToOne(targetEntity=Address.class, fetch=FetchType.LAZY, cascade=CascadeType.MERGE)
	@JoinColumn(name = "area_id")
	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}
	
	@Column(name = "floor_count")
	public Integer getFloorCount() {
		return floorCount;
	}

	public void setFloorCount(Integer floorCount) {
		this.floorCount = floorCount;
	}

	@Column(name = "room_count")
	public Integer getRoomCount() {
		return roomCount;
	}

	public void setRoomCount(Integer roomCount) {
		this.roomCount = roomCount;
	}

	@Column(name = "build_time")
	public String getBuildingTime() {
		return buildingTime;
	}

	public void setBuildingTime(String buildingTime) {
		this.buildingTime = buildingTime;
	}

	@Column(name = "elevator")
	//@Type(type="")
	public Boolean getElevator() {
		return elevator;
	}

	public void setElevator(Boolean elevator) {
		this.elevator = elevator;
	}

	@Column(name = "rent_pay_mode")
	public Integer getRentPayMode() {
		return rentPayMode;
	}

	public void setRentPayMode(Integer rentPayMode) {
		this.rentPayMode = rentPayMode;
	}

	@Column(name = "deposit_fee_type")
	public Integer getDepositFeeType() {
		return depositFeeType;
	}

	public void setDepositFeeType(Integer depositFeeType) {
		this.depositFeeType = depositFeeType;
	}

	@Column(name = "rent_cycle")
	public Integer getRentCycle() {
		return rentCycle;
	}

	public void setRentCycle(Integer rentCycle) {
		this.rentCycle = rentCycle;
	}

	// 房东+管理员
	@ManyToMany(targetEntity=LandlordUser.class)
	@JoinTable(name = "ra_building_landlorduser", 
		joinColumns = @JoinColumn(name="buildings_id"),
		inverseJoinColumns = @JoinColumn(name="user_id"))
	public List<LandlordUser> getLandlordUsers() {
		return landlordUsers;
	}

	public void setLandlordUsers(List<LandlordUser> landlordUsers) {
		this.landlordUsers = landlordUsers;
	}
	
	// 房东, 注:　relation_perm＝72057594037927935表示全部功能
	@ManyToOne(targetEntity=LandlordOwnerUser.class, fetch=FetchType.LAZY, optional=true)
	@JoinColumnsOrFormulas({
		@JoinColumnOrFormula(
				formula=@JoinFormula(value="(SELECT bl.user_id FROM ra_building_landlorduser bl"
						+ " left join ra_landlordpermission l on bl.user_id=l.user_id" 
						+ " where (l.admin_type=4 or l.admin_type=6) and bl.relation_type=2"
						+ " and bl.buildings_id=buildings_id)",
					referencedColumnName="user_id")),
	})
	public LandlordOwnerUser getLandlordUser() {
		/*if (getLandlordUsers() != null) {
			for (LandlordUser landlordUser : getLandlordUsers()) {
				if (landlordUser instanceof LandlordOwnerUser) {
					return (LandlordOwnerUser) landlordUser;
				}
			}
		}
		return null;*/
		return landlordUser;
	}

	public void setLandlordUser(LandlordOwnerUser landlordUser) {
		/*if (landlordUsers == null) {
			landlordUsers = new ArrayList<LandlordUser>();
			landlordUsers.add(landlordUser);
		} else {
			throw new ApplicationException("Invalid parameter");
		}*/
		this.landlordUser = landlordUser;
	}

	@Column(name = "version_id")
	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	@Column(name = "data_status")
	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}
	
	@Transient
	public int getRentableRoomCount(){
		int count = 0;
		if (getRooms() != null ) {
			count = getRooms().size();
		}
		return count;
	}
	
	@Transient
	public int getRentedRoomCount() {
		int roomCount = 0;
		List<Room> rooms = getRooms();
		if (rooms != null && rooms.size() > 0) {
			//统计已出租+预定的房间数
			for (Room room : rooms) {
				if (room.getRentState() == 0 || room.getRentState() == 2) {
					roomCount ++;
				}
			}
		}
		return roomCount;
	}
	
	@Temporal(TemporalType.TIMESTAMP)
	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	@Transient
	public Integer getRoomsPerFloor()
	{
		return roomsPerFloor;
	}

	public void setRoomsPerFloor(Integer roomsPerFloor)
	{
		this.roomsPerFloor = roomsPerFloor;
	}

	@Transient
	public Integer getRentType()
	{
		return rentType;
	}

	public void setRentType(Integer rentType)
	{
		this.rentType = rentType;
	}
}
